package com.wolfeyes.common.utils.redis;

import java.util.Date;

import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

//import com.bootdo.domain.po.common.TaskDO;
import com.wolfeyes.common.utils.character.ParamUtils;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @descript 自定义的redis底层实现类redisManager
 * @projectName bootdo
 * @className RedisManager.java
 * @author yanyl
 * @email 1991yanyl@163.com
 * @date 2018-07-11 15:53:58
 * @since 2018年07月12日上午11:37:39
 * @createTime 2018年06月09日 下午17:04:13
 * @version 1.0.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RedisManager {

	/**
	 * slf4j日志对象
	 */
	private static final Logger logger = LoggerFactory.getLogger(RedisManager.class);
	
    @Value("${spring.redis.host}")
    private String host = "127.0.0.1";

    @Value("${spring.redis.port}")
    private int port = 6379;

    // 0 - never expire! In seconds
    //浅译：0 - 永不过期!以秒为单位
    private int expire = 0;

    //timeout for jedis try to connect to redis server, not expire time! In milliseconds
    //浅译：配置jedis尝试连接到redis服务器的超时时间timeout，而不是过期时间 Expiration time!以毫秒为单位
    @Value("${spring.redis.timeout}")
    private int timeout = 0;

    @Value("${spring.redis.password}")
    private String password = "";

    /**
     * redis.clients.jedis.JedisPool
     * redis client for java
     * 浅译：redis缓存-客户端连接池对象jedisPool
     */
    private static JedisPool jedisPool = null;

	/**
	 * 使用lombok 插件 注解 @Data @Getter @Setter
	 * 参考博客：https://blog.csdn.net/icecoola_/article/details/77414572
	 * 参考博客：https://blog.csdn.net/cdyjy_litao/article/details/53759928
	 * 参考博客：https://blog.csdn.net/dorothy1224/article/details/79280591/
	 * 参考博客：http://www.blogjava.net/fancydeepin/archive/2012/07/12/lombok.html
	 */
    
    /**
     * 默认构造方法
     * /
    public RedisManager() {

    }

    public String getHost() {
        return host;
    }
    
    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getExpire() {
        return expire;
    }

    public void setExpire(int expire) {
        this.expire = expire;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
    */
    
    /**
     * @title redisManager for Initialize
     * @description 初始化方法
     * @param 
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return void
     * @throws Exception 异常
     */
    public void init() {
    	
    	// 开始初始化
        if (jedisPool == null) {
        	
        	// 非空判断
            if (!ParamUtils.isEmpty(this.password)) {
            	
            	// 创建redis缓存-客户端连接池对象jedisPool
                jedisPool = new JedisPool(new JedisPoolConfig(), this.host, this.port, this.timeout, this.password);
            
            // 非空判断
            } else if (this.timeout != 0) {
            	
            	// 创建redis缓存-客户端连接池对象jedisPool
                jedisPool = new JedisPool(new JedisPoolConfig(), this.host, this.port, this.timeout);
                
            } else {
            	
            	// 创建redis缓存-客户端连接池对象jedisPool
                jedisPool = new JedisPool(new JedisPoolConfig(), this.host, this.port);
            }

        }
    }

    /**
     * @title get value from redis
     * @description 根据属性key的字节数组，获取属性值value的字节数组
     * @param key 属性key的字节数组
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return byte[] 属性值value的字节数组
     * @throws Exception 异常
     */
    public byte[] get(byte[] key) {
    	
        byte[] value = null;
        
        Jedis jedis = jedisPool.getResource();
        
        try {
            value = jedis.get(key);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return value;
    }

    /**
     * @title set key and value to redis
     * @description 根据属性key的字节数组，属性值value的字节数组；存储至redis缓存
     * @param key 属性key的字节数组
     * @param vaule 属性值value的字节数组
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return boolean result 操作是否成功：true/成功，false/失败
     * @throws Exception 异常
     */
    public boolean set(byte[] key, byte[] value) {
    	
    	String result = null;
    	
        Jedis jedis = jedisPool.getResource();
        
        try {
        	result = jedis.set(key, value);
            if (this.expire != 0) {
                jedis.expire(key, this.expire);
            }
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        
        return "OK".equalsIgnoreCase(result) ? true : false;
    }

    /**
     * @title set key and value in expire to redis
     * @description 根据属性key的字节数组，属性值value的字节数组，过期时间expire；存储至redis缓存
     * @param key 属性key的字节数组
     * @param value 属性值value的字节数组
     * @param expire 过期时间（即：何时失效）
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return boolean result 操作是否成功：true/成功，false/失败
     * @throws Exception 异常
     */
    public boolean set(byte[] key, byte[] value, int expire) {
    	
    	String result = null;
    	
        Jedis jedis = jedisPool.getResource();
        
        try {
        	result = jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, expire);
            }
        }catch (Exception e) {
        	logger.error("redisManager set [{},{}] error:{}", key, value, e.getMessage());
		} finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        
        return "OK".equalsIgnoreCase(result) ? true : false;
    }

    /**
     * @title del key-value from redis
     * @description 根据属性key的字节数组，从redis缓存中删除此键值对：key-value
     * @param key 属性key的字节数组
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return void
     * @throws Exception 异常
     */
    public void del(byte[] key) {
    	
        Jedis jedis = jedisPool.getResource();
        try {
            jedis.del(key);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        
    }

    /**
     * @title exist key from redis
     * @description 判断redis缓存中是否存在此key值
     * @param key 属性key
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return boolean result 是否存在此key值：true/存在，false/不存在
     * @throws Exception 异常
     */
    public boolean exist(String key) {
    	
        boolean result = false;
        
        try {
            Jedis redis = jedisPool.getResource();
            
            // 判断redis缓存中是否存在此key值
            result = redis.exists(key);
            
            //jedisPool.returnResource(redis);
            redis.close();
        } catch (Exception e) {
        	logger.error("redis exist [{}] error:{}" ,key,e.getMessage());
        }
        
        return result;
    }

    /**
     * @title keys from redis
     * @description 获取redis缓存中所有键-keys
     * @param pattern regex正则表达式
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return Set<byte[]> keys 所有键-keys的Set集合
     * @throws Exception 异常
     */
    public Set<byte[]> keys(String pattern) {
    	
        Set<byte[]> keys = null;
        
        Jedis jedis = jedisPool.getResource();
        
        try {
        	
        	// 获取redis缓存中所有键-keys
            keys = jedis.keys(pattern.getBytes());
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return keys;
    }
    
    /**
     * @title flushDB from redis
     * @description 清空redis缓存-flushDB
     * @param 
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return void
     * @throws Exception 异常
     */
    public void flushDB() {
    	
        Jedis jedis = jedisPool.getResource();
        
        try {
        	
        	// 清空redis缓存-flushDB
            jedis.flushDB();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
    
    /**
     * @title dbSize from redis
     * @description 获取redis缓存大小-dbSize
     * @param 
     * @author yanyl
     * @since 2018年10月08日上午13:37:39
     * @return void
     * @throws Exception 异常
     */
    public Long dbSize() {
    	
        Long dbSize = 0L;
        
        Jedis jedis = jedisPool.getResource();
        
        try {
        	
        	// 获取redis缓存大小-dbSize
            dbSize = jedis.dbSize();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return dbSize;
    }

}

